import {BrowserWindowConstructorOptions} from 'electron'

/** 对象 */
export type E3Object = { [key: string]: any }

/** 环境名称配置 */
export type Env = {
    /** 生产环境名称 */
    PROD: string
    /** 开发环境名称 */
    DEV: string
    /** 本地环境名称 */
    LOCAL: string
}

/** 目录配置（相对于项目根目录） */
export type Directorys = {
    /** 项目根目录 */
    root: string
    /** 前端源码 */
    frontendSrc: string
    /** 后端源码 */
    electronSrc: string
    /** 公共目录 */
    public: string
    /** 前端发布目录 */
    frontendDst: string
    /** 后端发布目录 */
    electronDst: string
    /** 静态图片目录 */
    images: string
    /** golang 子项目目录 */
    go: string
    /** python 子项目目录 */
    python: string
    /** ee-bin 命令配置目录 */
    cmd: string
    /** 日志目录 */
    log: string
    /** 数据目录 */
    data: string
    /** 临时目录（开发时使用） */
    temp: string
    /** 日志目录-开发 */
    logDev: string
    /** 数据目录-开发 */
    dataDev: string
    /** APP 发布目录 */
    appDist: string
    /** 打包配置目录 */
    builderConfig: string
    /** icon 目录 */
    icons: string
    /** appData 目录，用户自管理用户数据时时使用 */
    appData: string
    /** userData 目录，用户自管理用户数据时时使用 */
    userData: string
}

/** 用户数据，升级或卸载时需要保留的数据 */
export type UserData = {
    /** 目录 */
    directorys: string[]
    /** 文件 */
    files: string[]
}

/** 开发配置-前端 */
export type DevFrontend = {
    /** frontend 目录 */
    directory?: string
    /** 命令 */
    cmd?: string
    /** 参数 */
    args?: string[]
    /** 协议 'http://' 'https://' 'file://' */
    protocol: 'http://' | 'https://' | 'file://'
    /** 入口文件 'file://' 使用 file://...index.html，'http://' 使用 index.html */
    indexPath: string
    /** 主机 'http://' 或 'https://' 协议时有效 */
    hostname?: string
    /** 端口 'http://' 或 'https://' 协议时有效 */
    port?: number
    /** true 强制加载前端服务 */
    force?: boolean
    /** true 串行执行命令（非常住进程才能使用） */
    sync?: boolean
}

/** 开发配置-electron */
export type DevElectron = {
    /** electron 工作目录 */
    directory?: string
    /** 命令 */
    cmd?: string
    /** 参数 */
    args?: string[]
    /** '' 为关闭，'/public/html/loading.html' 为loading页面 */
    loadingPage: string
    /** true 监听文件变化，如果监听，那么每次文件变化都会重新执行命令 */
    watch?: boolean
    /** true 串行执行命令（非常住进程才能使用） */
    sync?: boolean
    /** 延迟启动时间，单位：毫秒 */
    delay?: number
}

/** 开发配置 */
export type Dev = {
    /** 前端 */
    frontend: DevFrontend
    /** 后端 */
    electron: DevElectron
}

/** APP-日志配置 */
export type AppLogger = {
    /** 类型 */
    type?: 'application'
    /** 保存路径 */
    dir?: string
    /** 编码 */
    encoding?: 'utf8' | 'utf-8' | 'UTF8' | 'UTF-8'
    /** 环境 */
    env?: string
    /** 日志等级 */
    level?: 'error' | 'warn' | 'info' | 'debug' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
    /** 控制台日志等级 */
    consoleLevel?: 'error' | 'warn' | 'info' | 'debug' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
    /** 是否禁用 console */
    disableConsoleAfterReady?: boolean
    /** 是否输出JSON */
    outputJSON?: boolean
    /** 是否启用 buffer */
    buffer?: boolean
    /** 应用日志名称 */
    appLogName?: string
    /** 核心日志名称 */
    coreLogName?: string
    /** 代理日志名称 */
    agentLogName?: string
    /** 错误日志名称 */
    errorLogName?: string
    /** 核心日志配置 */
    coreLogger?: E3Object
    /** 生成环境是否允许 debug */
    allowDebugAtProd?: boolean
    /** 是否启用性能计时器 */
    enablePerformanceTimer?: boolean
    /** 切割日志方式，仅支持 day 按天 */
    rotator?: 'day' | ''
}

/** APP-远程web地址配置 */
export type AppRemote = {
    /** 是否启用 */
    enable?: boolean
    /** 远程地址 */
    url?: string
}

/** APP-内置socket服务-跨域配置 */
export type AppSocketCors = {
    /** http协议时，要设置允许跨域 */
    origin?: boolean
}

/** APP-内置socket服务配置 */
export type AppSocket = {
    /** 是否启用 */
    enable?: boolean
    /** 默认端口 */
    port?: number
    /** 默认路径名称 */
    path?: string
    /** 客户端连接超时时间 */
    connectTimeout?: number
    /** 心跳检测超时时间 */
    pingTimeout?: number
    /** 心跳检测间隔 */
    pingInterval?: number
    /** 每条消息的数据最大值（字节） */
    maxHttpBufferSize?: number
    /** http轮询和websocket */
    transports?: string[]
    /** 跨域配置 */
    cors?: AppSocketCors
    /** 自定义通道名称，默认socket-channel */
    channel?: string
}

/** APP-内置http服务-启用https配置 */
export type AppHttpHttps = {
    /** 是否启用 */
    enable?: boolean
    /** key文件 */
    key?: string
    /** cert文件 */
    cert?: string
}

/** APP-内置http服务-跨域配置 */
export type AppHttpCors = {
    /** 允许的域 */
    origin?: string
}

/** APP-内置http服务-请求体配置 */
export type AppHttpBody = {
    /** 是否解析 multipart/form-data 类型的请求 */
    multipart?: boolean
    /** 上传表单配置 multipart/form-data */
    formidable?: {
        /** 上传的文件是否保留原始扩展名 */
        keepExtensions?: boolean
    }
}

/** APP-内置http服务-过滤请求配置 */
export type AppFilterRequest = {
    /** 要过滤的请求uri */
    uris?: string[]
    /** 任意数据类型 */
    returnData?: string
}

/** APP-内置http服务配置 */
export type AppHttp = {
    /** 是否启用 */
    enable?: boolean
    /** 启用https配置 */
    https?: AppHttpHttps
    /** 协议 */
    protocol?: 'http://' | 'https://'
    /** 监听主机名或IP */
    host?: string
    /** 监听端口 */
    port?: number
    /** 跨域配置 */
    cors?: AppHttpCors
    /** 请求体配置 */
    body?: AppHttpBody
    /** 过滤请求 */
    filterRequest?: AppFilterRequest
}

/** APP-主进程配置 */
export type AppMainServer = {
    /** 协议 */
    protocol?: 'file://' | 'http://' | 'https://'
    /** 前端资源入口文件 */
    indexPath?: string
    /** 兼容electron参数，https://www.electronjs.org/zh/docs/latest/api/browser-window#winloadurlurl-options */
    options?: E3Object
    /** 接管。如果想加载一个go web程序，来替代 protocol */
    takeover?: string
    /** 加载一个loading页，一般不用开启 */
    loadingPage?: string
    /** 通信频道路径分割符，v4 版本后，默认为 / */
    channelSeparator?: string
}

/** APP-主进程配置 */
export type AppException = {
    /** 主进程 */
    mainExit?: boolean
    /** jobs 子进程 */
    childExit?: boolean
    /** 渲染进程 */
    rendererExit?: boolean
}

/** APP-jobs 任务配置 */
export type AppJob = {
    /** 是否 打印/记录 进程间通信的消息log */
    messageLog?: boolean
}

/** APP配置 */
export type App = {
    /** App 项目名称 */
    name: string
    /** App 友好名称（软件 title 或安装快捷方式等） */
    title: string
    /** 发布名称，安装包、打包后的程序使用 */
    distName : string
    /** App 描述 */
    description: string
    /** App 仓库 */
    repository: string
    /** App 关键字 */
    keywords: string[]
    /** App 作者 */
    author: string
    /** App 开源协议 */
    license: string
    /** 内容安全策略域名 */
    contentSecurityPolicyDomains : string[],
    /** 是否开启 DevTools */
    openDevTools?: boolean | Object
    /** 单实例模式，true 仅允许运行一个实例 */
    singleLock?: boolean
    /** 主窗口配置 */
    windowsOption?: BrowserWindowConstructorOptions
    /** 日志日志 */
    logger?: AppLogger
    /** 远程web地址 */
    remote?: AppRemote
    /** 内置socket服务 */
    socketServer?: AppSocket
    /** 内置http服务 */
    httpServer?: AppHttp
    /** 主进程配置 */
    mainServer?: AppMainServer
    /** 异常捕获 */
    exception?: AppException
    /** jobs 任务 */
    jobs?: AppJob
    /**
     * 跨语言服务，例子：
     * cross = {
     *   // 自定义服务名
     *   go: {
     *     // 是否开启
     *     enable: true,
     *     // 可执行程序名
     *     name: 'goapp',
     *     // 参数
     *     args: ['--port=7073'],
     *     // 可执行程序退出时，是否退出整个桌面程序
     *     appExit: true,
     *   }
     * };
     */
    cross?: E3Object
}

/** NSIS打包配置-目录 */
export type BuilderDirectories = {
    /** 输出目录 */
    output?: string
}

/** 打包配置-nsis */
export type BuilderNSIS = {
    /** GUID */
    guid?: string
    /** 是否启用一键安装模式 */
    oneClick?: boolean
    /** 是否为所有用户安装（默认是Program Files） */
    perMachine?: boolean
    /** 是否允许提权（管理员权限） */
    allowElevation?: boolean
    /** 是否允许用户自定义安装路径 */
    allowToChangeInstallationDirectory?: boolean
    /** false 为忽略警告（即不把警告当错误，否则警告会造成打包失败） */
    warningsAsErrors?: boolean
    /** 卸载时是否删除应用数据目录（如用户配置、缓存等） */
    deleteAppDataOnUninstall?: boolean
    /** 安装图标 */
    installerIcon?: string
    /** 卸载图标 */
    uninstallerIcon?: string
    /** 界面图标 */
    installerHeaderIcon?: string
    /** 是否生成差异更新包 */
    differentialPackage?: boolean
    /** 是否创建桌面快捷方式 */
    createDesktopShortcut?: boolean
    /** 是否创建开始菜单快捷方式 */
    createStartMenuShortcut?: boolean
    /** 快捷方式名称 */
    shortcutName?: string
    /** 引入配置文件 */
    include?: string
    /** 语言 */
    installerLanguages?: 'zh_CN'
}

/** 打包-发布配置 */
export type BuilderPublish = {
    /**
     * 更新服务器提供商
     * github  - 从 GitHub Releases 获取更新，适用于开源项目或使用 GitHub 托管的项目
     * generic - 从自定义 HTTP(S) 服务器获取更新，适用于私有部署或企业内网分发
     * s3      - 从 AWS S3 存储桶获取更新，适用于 AWS 云存储托管的项目
     * spaces  - 从 DigitalOcean Spaces 获取更新，适用于 DigitalOcean 用户
     * bintray - 从 JFrog Bintray 获取更新（已弃用），旧项目可能还在使用
     */
    provider?: 'github' | 'generic' | 's3' | 'spaces' | 'bintray'
    /** 发布地址 */
    url?: string
}

/** 打包-windows配置 */
export type BuilderWin = {
    /** 应用程序在 Windows 系统中的图标 */
    icon?: string
    /** 打包名称 */
    artifactName?: string
    /** 目标打包方式 */
    target: string[]
}

/** 打包-linux配置 */
export type BuilderLinux = {
    /** 应用程序在 linux 系统中的图标 */
    icon?: string
    /** 打包名称 */
    artifactName?: string
    /** 目标打包方式 */
    target: string[]
    /** 设置应用程序的分类（用于 Linux 桌面环境的菜单分类） */
    category?: 'Utility'
}

/** 打包-mac配置 */
export type BuilderMac = {
    /** 应用程序在 mac 系统中的图标 */
    icon?: string
    /** 打包名称 */
    artifactName?: string
    /** 是否启用 macOS 深色模式（Dark Mode）支持 */
    darkModeSupport?: boolean
    /** 是否启用 Hardened Runtime（强化运行时），用于通过 macOS 公证（Notarization）要求 */
    hardenedRuntime?: boolean
}

/** 打包-复制资源 */
export type BuilderExtraResources = {
    /** 源资源 */
    from?: string
    /** 目标资源 */
    to?: string
    /** 过滤 ["** /*", "!*.tmp"] 包含所有文件，排除.tmp后缀 */
    filter?: string[]
}

/** 打包-脚本路径（非标准配置） */
export type Builder$Scripts = {
    /** windows 打包配置文件路径 */
    windows?: string
    /** linux 打包配置文件路径 */
    linux?: string
    /** mac 打包配置文件路径 */
    mac?: string
    /** nsh 脚本文件路径 */
    nsh?: string
}

/** 额外元数据 */
export type BuilderExtraMetadata = {
    /** 主页 */
    homepage?: string
}

/** 打包配置 */
export type Builder = {
    /** 项目名称 */
    productName?: string
    /** AppID 如：red.exi.app */
    appId?: string
    /** 版权信息 */
    copyright?: string
    /** 目录 */
    directories?: BuilderDirectories
    /** 复制资源 */
    extraResources?: BuilderExtraResources[]
    /** 是否 asar 打包 */
    asar?: boolean
    /**
     * 要打包的文件
     * ** /* 代表全部文件（**后没有空格）
     * !cmd/ 代表排除
     */
    files?: string[]
    /** nsis */
    nsis?: BuilderNSIS
    /** 发布 */
    publish?: BuilderPublish
    /** 额外元数据 */
    extraMetadata?: BuilderExtraMetadata
    /** windows 专用配置 */
    win?: BuilderWin
    /** linux 专用配置 */
    linux?: BuilderLinux
    /** mac 专用配置 */
    mac?: BuilderMac
    /** 打包脚本路径（非标准配置） */
    $scripts?: Builder$Scripts
    /**
     * 是否安装到系统盘根目录（非标准配置）
     * true  : 安装到 [系统盘符]:\MyApp
     * false : 安装到默认安装目录 [系统盘符]:\Program Files\MyApp
     * [系统盘符] 视系统所在盘符为准
     */
    $installToSystemDriveRoot?: boolean
}

/** 数据库配置 */
export type Database = {
    sqlite3DBFiles: E3Object
}

/** 总配置 */
export type Configs = {
    /** 环境名称配置 */
    env: Env
    /** 目录配置 */
    directorys: Directorys
    /** 开发配置 */
    dev: Dev
    /** APP配置 */
    app: App
    /** 打包配置 */
    builder: Builder
    /** 用户数据，升级或卸载时需要保留的数据 */
    userData: UserData
    /** 数据库配置 */
    database: Database
}
